/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author         Notes
 * 2021-04-20     yaoyufan       the first version
 */
#include "datadeal.h"


CARD card;
RTCTIME rtc_time;


//卡号读取
void Mfrc_Thread_Entry(void *parameter)
{
    unsigned char status;
    char TagType[2], SelectedSnr[4];
    while (1)
    {
        status = PcdRequest(PICC_REQALL, TagType);
        if(!status)
        {
            status = PcdAnticoll(SelectedSnr);
            if(!status)
            {
                status=PcdSelect(SelectedSnr);
                if(!status)
                {
                    //rt_kprintf("%x%x%x%x\n",SelectedSnr[0], SelectedSnr[1],SelectedSnr[2],SelectedSnr[3]);
                    rt_mb_send(Uid_Mb, (rt_uint32_t)SelectedSnr);
                }
             }
         }
        rt_thread_mdelay(2000);
      }
}

//卡号处理
void CardDeal_Thread_Entry(void *parameter)
{
    char *SelectedSnr;

    while(1)
    {

        if(rt_mb_recv(Uid_Mb, (rt_uint32_t *)&SelectedSnr, RT_WAITING_FOREVER) == RT_EOK)
        {
            //rt_kprintf("%x%x%x%x\n",SelectedSnr[0], SelectedSnr[1],SelectedSnr[2],SelectedSnr[3]);
            ICCard_Deal(SelectedSnr);
        }


        rt_thread_mdelay(1000);

    }
}

//UID处理函数
void ICCard_Deal(char *SelectedSnr)
{
    uint8_t res = -1;
    uint8_t AllowTime[4];
    uint8_t Er_Card;
    int fd = -1;
    uint8_t er_str[4]=" ER";
    uint8_t ok_str[4]=" OK";
    char snr_str[8];

    RTC_Get();
    res = Search_Card(SelectedSnr, COMOrMAN);
    //rt_kprintf("Card Type = %d\n", res);
    if(res == FALSE)
    {
        Er_Card = 1;//非法卡
        rt_mb_send(Result_Mb, (rt_uint32_t)Er_Card);

    }else {
        if (res == COMMON) {
            Read_ComCardTime(AllowTime);
        }
        Er_Card = 1;
        if (res == MANAGE||(((AllowTime[0]*60+AllowTime[1])<=(rtc_time.hour*60+rtc_time.min))
                          &&((AllowTime[2]*60+AllowTime[3])>=(rtc_time.hour*60+rtc_time.min))))
        {
            Er_Card = 0;

        }
        rt_mb_send(Result_Mb, (rt_uint32_t)Er_Card);
    }

    sprintf(&snr_str, "%x%x%x%x ", SelectedSnr[0],SelectedSnr[1],SelectedSnr[2],SelectedSnr[3]);
    strcat(rtc_time.time_str, snr_str);
    if(Er_Card == 0)
    {
        strcat(rtc_time.time_str, ok_str);
        ssd1306_SetCursor(50, 40);
        ssd1306_WriteString("YES", Font_11x18, White);
        rt_timer_start(SSD1306_Timer);
    }
    else
    {
        strcat(rtc_time.time_str, er_str);
        ssd1306_SetCursor(50, 40);
        ssd1306_WriteString("NO", Font_11x18, White);
      rt_timer_start(SSD1306_Timer);
    }


    fd = open("/record.txt", O_CREAT|O_WRONLY|O_APPEND);
    if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
    write(fd, rtc_time.time_str, strlen(rtc_time.time_str));
    write(fd, "\n", 1);
    close(fd);
}

//查询卡号函数
//CardSnr----卡号
//Type-------COMMON,MANAGE添卡用,COMOrMAN查询用
//返回值-----成功TRUE,失败FALSE
uint8_t Search_Card(uint8_t *CardSnr, uint8_t Type)
{
    int fd = -1;
    int size = 0;;
    uint8_t card_buf[256];

    switch (Type)
    {
        case COMMON://普通卡
            fd = open("/common_card.bin", O_RDONLY);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size =read(fd, card_buf, sizeof(card_buf));
            if(size < 0) rt_kprintf("read failed on %d\n", __LINE__);
            close(fd);
            for (int var = 0;  var < size/4; ++ var) {
                if(CardSnr[0]==card_buf[4*var]&&CardSnr[1]==card_buf[4*var+1]&&
                   CardSnr[2]==card_buf[4*var+2]&&CardSnr[3]==card_buf[4*var+3])
                {
                    card.uid_position = var;
                    return TRUE;
                }

            }
            return FALSE;
        case MANAGE://管理员卡
            fd = open("/manage_card.bin", O_RDONLY);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size =read(fd, card_buf, sizeof(card_buf));
            if(size < 0) rt_kprintf("read failed on %d\n", __LINE__);
            close(fd);
            for (int var = 0;  var < size/4; ++ var) {
                if(CardSnr[0]==card_buf[4*var]&&CardSnr[1]==card_buf[4*var+1]&&
                   CardSnr[2]==card_buf[4*var+2]&&CardSnr[3]==card_buf[4*var+3])
                {
                    card.uid_position = var;
                    return TRUE;
                }
            }
            return FALSE;
        case COMOrMAN:
            fd = open("/manage_card.bin", O_RDONLY);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size =read(fd, card_buf, sizeof(card_buf));
            if(size < 0) rt_kprintf("read failed on %d\n", __LINE__);
            close(fd);
            for (int var = 0;  var < size/4; ++ var) {
                if(CardSnr[0]==card_buf[4*var]&&CardSnr[1]==card_buf[4*var+1]&&
                   CardSnr[2]==card_buf[4*var+2]&&CardSnr[3]==card_buf[4*var+3])
                    return MANAGE;
            }

            fd = open("/common_card.bin", O_RDONLY);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size =read(fd, card_buf, sizeof(card_buf));
            if(size < 0) rt_kprintf("read failed on %d\n", __LINE__);
            close(fd);
            for (int var = 0;  var < size/4; ++ var) {
                if(CardSnr[0]==card_buf[4*var]&&CardSnr[1]==card_buf[4*var+1]&&
                   CardSnr[2]==card_buf[4*var+2]&&CardSnr[3]==card_buf[4*var+3])
                    return COMMON;
            }
            return FALSE;
        default:
            return FALSE;
    }
}

//添管理员卡
uint8_t Add_ManageCard(uint8_t *CardSnr)
{
    uint8_t res;
    int fd = -1;
    int size = -1;
    res = Search_Card(CardSnr,MANAGE);
    switch(res)
    {
        case FALSE:
            fd = open("/manage_card.bin", O_WRONLY|O_APPEND|O_CREAT);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size = write(fd, CardSnr, 4);
            if(size < 0) rt_kprintf("write failed on %d\n", __LINE__);
            close(fd);
            return TRUE;
        default:
            return FALSE;
    }
}

//添普通卡
uint8_t Add_CommonCard(uint8_t *CardSnr)
{
    uint8_t res;
    int fd = -1;
    int size = -1;
    res = Search_Card(CardSnr,COMMON);
    switch(res)
    {
        case FALSE:
            fd = open("/common_card.bin", O_WRONLY|O_APPEND|O_CREAT);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            size = write(fd, CardSnr, 4);
            if(size < 0) rt_kprintf("write failed on %d\n", __LINE__);
            close(fd);
            return TRUE;
        default:
            return FALSE;

    }
}

//删卡函数
//CardSnr----卡号
//TypeName---类型
//返回值-----成功返回TRUE，失败返回FALSE
uint8_t Delete_Card(uint8_t *CardSnr, uint8_t TypeName)
{
    uint8_t res;
    int fd = -1;
    int size = -1;
    uint8_t temp[4] = {0,0,0,0};

    if(TypeName == COMMON)
    {
        res = Search_Card(CardSnr, COMMON);
        if(res == FALSE) return FALSE;
        else {
            fd = open("/common_card.bin", O_RDWR);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            lseek(fd, card.uid_position*4, SEEK_SET);
            size = write(fd, temp, 4);
            if(fd < 0) rt_kprintf("write failed on %d\n", __LINE__);
            close(fd);
            return TRUE;
        }

    }else {
        res = Search_Card(CardSnr, MANAGE);
        if(res == FALSE) return FALSE;
        else {
            fd = open("/manage_card.bin", O_RDWR);
            if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
            lseek(fd, card.uid_position*4, SEEK_SET);
            size = write(fd, temp, 4);
            if(fd < 0) rt_kprintf("write failed on %d\n", __LINE__);
            close(fd);
            return TRUE;
        }
    }
}

//删除所有卡
void Delete_AllCard(void)
{
    int fd = -1;
    fd = open("/common_card.bin", O_TRUNC);
    if(fd < 0) rt_kprintf("open fd failed\n");
    close(fd);

    fd = open("/manage_card.bin", O_TRUNC);
    if(fd < 0) rt_kprintf("open fd failed\n");
    close(fd);
}

//设置通行时间
void Set_ComCardTime(uint8_t *temp)
{
    int fd = -1;
    int size = -1;

    fd = open("/comcardtime.bin", O_CREAT|O_WRONLY);
    if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
    size = write(fd, temp, 4);
    if(size < 0) rt_kprintf("write failed on %d\n", __LINE__);
    close(fd);
}

//读取通行时间
void Read_ComCardTime(uint8_t *temp)
{
    int fd = -1;
    int size = -1;

    fd = open("/comcardtime.bin", O_RDONLY);
    if(fd < 0) rt_kprintf("open failed on %d\n", __LINE__);
    size = read(fd, temp, 4);
    if(size < 0) rt_kprintf("read failed on %d\n", __LINE__);
    close(fd);
}


//时间获取
void RTC_Get(void)
{
    time_t now;
    uint8_t hour_str[2], min_str[2], sec_str[2];
    uint8_t year_str[4], month_str[3], day_str[2];
    uint8_t res = -1;

    now = time(RT_NULL);
    rtc_time.time_str = ctime(&now);
    hour_str[0] = rtc_time.time_str[11];hour_str[1] = rtc_time.time_str[12];
    min_str[0]  = rtc_time.time_str[14];min_str[1]  = rtc_time.time_str[15];
    sec_str[0]  = rtc_time.time_str[17];sec_str[1]  = rtc_time.time_str[18];
    day_str[0]  = rtc_time.time_str[8];day_str[1]   = rtc_time.time_str[9];
    year_str[0] = rtc_time.time_str[20];year_str[1] = rtc_time.time_str[21];
    year_str[2] = rtc_time.time_str[22];year_str[3] = rtc_time.time_str[23];
    month_str[0]= rtc_time.time_str[4]; month_str[1]= rtc_time.time_str[5];
    month_str[2]= rtc_time.time_str[6];

    if(!strcmp(month_str, "Jan"))
        rtc_time.month = 1;
    else if (!strcmp(month_str, "Feb"))
        rtc_time.month = 2;
    else if (!strcmp(month_str, "Mar"))
        rtc_time.month = 3;
    else if (!strcmp(month_str, "Apr"))
        rtc_time.month = 4;
    else if (!strcmp(month_str, "May"))
        rtc_time.month = 5;
    else if (!strcmp(month_str, "Jun"))
        rtc_time.month = 6;
    else if (!strcmp(month_str, "Jul"))
        rtc_time.month = 7;
    else if (!strcmp(month_str, "Aug"))
        rtc_time.month = 8;
    else if (!strcmp(month_str, "Sep"))
        rtc_time.month = 9;
    else if (!strcmp(month_str, "Oct"))
        rtc_time.month = 10;
    else if (!strcmp(month_str, "Nov"))
        rtc_time.month = 11;
    else if (!strcmp(month_str, "Dec"))
        rtc_time.month = 12;
    rtc_time.hour = atoi(hour_str);
    rtc_time.min  = atoi(min_str);
    rtc_time.sec  = atoi(sec_str);
    rtc_time.day  = atoi(day_str);
    rtc_time.year = atoi(year_str);

}
